/*
* BankService
*
* r4
*
* GNU General Public License v3.0
*/

package com.acme.bankapp.service.bank;

import java.util.*;
import java.io.*;

import com.acme.bankapp.domain.account.*;
import com.acme.bankapp.domain.bank.*;
import com.acme.bankapp.domain.client.*;
import com.acme.bankapp.exceptions.*;

public class BankService {

	private Bank bank;
	private String feedFile = "";
	
	private static String stringFormat = "accounttype=%s;balance=%d;overdraft=%d;name=%s;gender=%s;\r\n";
	private static String duplicatedWarning = "Warning: db contains duplicated client entries";
	
	public BankService(Bank bank) {
		this.bank = bank;
	}
	
	public void setFeedFile(String feedFile) {
		this.feedFile = feedFile;
	}
	
	public void addClient(Client client, Account... accounts) throws ClientExistsException {
		this.bank.addClient(client);
		
		for(Account a : accounts) {
			client.addAccount(a);
		}
		
		try {
			saveBank();
		} catch(IOException ex) {
			
		}
	}
	
	@Override
	public String toString() {
		StringBuffer stringBuffer = new StringBuffer();
		
		for(Client client : this.bank.getClients()) {
			stringBuffer.append(client);
		}
		
		return stringBuffer.toString();
	}
	
	/*
	 *  Will be saved only first client's account
	 *  as stated in labguide
	 */
	public void saveBank() throws IOException {
		File file = new File(feedFile);
		FileWriter writer = new FileWriter(file);
		
		for(Client client : this.bank.getClients()) {
			//for(Account account : client.getAccounts()) {
			Account account = client.getAccounts().get(0);
			
			writer.write(String.format(stringFormat, (account instanceof CheckingAccount ? "c" : "s"), 
					account.getBalance(), (account instanceof CheckingAccount ? ((CheckingAccount)account).getOverdraft() : 0),
					client.getName(), client.getGender() == Gender.MALE ? "m" : "f"));
			
			//}
		}
		
		writer.close();
	}
	
	public void addClientByString(String str) throws ClientExistsException {
		Client newClient;
		Account newAccount;
		
		String accountType = "c";
		String name = "";
		String gender = "m";
		double balance = 0;
		double overdraft = 0;
		
		Scanner settingScanner = new Scanner(str);
		settingScanner.useDelimiter(";");
		while(settingScanner.hasNext()) {
			String setting = settingScanner.next();
			String[] values = setting.split("=");
			
			if(values[0].equals("accounttype")) {
				accountType = values[1];
			} else if(values[0].equals("balance")) {
				balance = Double.parseDouble(values[1]);
			} else if(values[0].equals("overdraft")) {
				overdraft = Double.parseDouble(values[1]);
			} else if(values[0].equals("name")) {
				name = values[1];
			} else if(values[0].equals("gender")) {
				gender = values[1];
			}
		}
		
		if(name.equals("")) {
			settingScanner.close();
			return;
		}
		
		if(accountType.equals("c")) {
			newAccount = new CheckingAccount(balance, overdraft);
		} else {
			newAccount = new SavingsAccount(balance);
		}
		
		newClient = new Client(name, gender.equals("m") ? Gender.MALE : Gender.FEMALE);
		newClient.addAccount(newAccount);
		
		this.bank.addClient(newClient);
		
		settingScanner.close();
	}
	
	/*
	 *  Allowing only one account per client 
	 */
	public void readBank() throws FileNotFoundException {
		Scanner lineScanner;
		
		if(feedFile == null) {
			return;
		}
		
		this.bank.clear();
		
		lineScanner = new Scanner(new File(feedFile));
		lineScanner.useDelimiter("\n");
		
		while(lineScanner.hasNext()) {
			try {
				addClientByString(lineScanner.next());
			} catch(ClientExistsException ex) {
				System.out.println(duplicatedWarning);
			}
		}
		
		lineScanner.close();
	}
	
}
